package com.jiang.annotation.aop.retryable;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Slf4j
public class RetryableAspect {

    @Around("@annotation(retryable)")
    public Object retry(ProceedingJoinPoint joinPoint, Retryable retryable) throws Throwable {
        int maxAttempts = retryable.maxAttempts(); // 获取最大重试次数
        int attemptCount = 0;
        Exception finalException = null;
        do {
            attemptCount++;
            try {
                return joinPoint.proceed(); // 执行方法
            } catch (Exception e) {
                log.error(e.getMessage());
                Signature signature = joinPoint.getSignature();
                log.info("{}.{} retry for the {}th time",
                        signature.getDeclaringTypeName(),
                        signature.getName(),
                        attemptCount);
                if(attemptCount == maxAttempts){
                    finalException = e;
                }
            }
        } while (attemptCount < maxAttempts);
        log.info("has try for {} times, failed", maxAttempts);
        return finalException;
    }
}
